package com.one.rope.mvp.basecore.bean;

import com.fasterxml.jackson.annotation.JsonProperty;
import com.one.rope.mvp.basecore.exception.BaseException;
import com.one.rope.mvp.basecore.util.JsonUtils;
import com.one.rope.mvp.basecore.util.StringUtils;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

/**
 * @author Weijian.liu
 * @desc 接口返回通用对象
 * @date 2018/11/26
 */
@Slf4j
@Data
public class ResponseGeneric<T extends Object> {

  protected int code = BaseBusinessMessage.SUCCESS_CODE;

  protected String msg = BaseBusinessMessage.SUCCESS_MESSAGE;

  /**
   * 接口响应时间
   */
  @JsonProperty("usage_time")
  private long usageTime;

  /**
   * 数据对象
   */
  protected T data;

//  /**
//   * 当前时间戳
//   */
//  private long timestamp = System.currentTimeMillis();

  public ResponseGeneric() {
  }

  public ResponseGeneric(T data) {
    this.data = data;
  }

  public ResponseGeneric(ResponseMessage responseMessage) {
    this(responseMessage, null);
  }

  public ResponseGeneric(int code, String message) {
    this.code = code;
    this.msg = message;
  }

  public ResponseGeneric(ResponseMessage responseMessage, T data) {
    this.code = responseMessage.getCode();
    this.msg = responseMessage.getMsg();
    this.data = data;
  }

  public ResponseGeneric(int code, String message, T data) {
    this.code = code;
    this.msg = message;
    this.data = data;
  }

  /**
   * 是否成功的状态
   */
  public boolean success() {
    return this.code == BaseBusinessMessage.SUCCESS_CODE;
  }

  @Override
  public String toString() {
    return JsonUtils.objectToFasterxmlJsonString(this);
  }

  public static <T> ResponseGeneric<T> successObject(T object) {
    return new ResponseGeneric<>(object);
  }

  public static <T> ResponseGeneric<T> userFailure(ResponseMessage message) {
    return new ResponseGeneric<>(message);
  }

  public static <T> ResponseGeneric<T> userFailure(ResponseMessage message, T data) {
    return new ResponseGeneric<>(message, data);
  }

  public static <T> ResponseGeneric<T> systemError(Throwable e) {
    return systemError(e, null);
  }

  public static <T> ResponseGeneric<T> userError(BaseException e) {
    return new ResponseGeneric<>(e.getCode(), e.getMsg());
  }

  public static <T> ResponseGeneric<T> systemError(Throwable e, String prefix) {
    try {
      if (e instanceof BaseException) {
        BaseException exception = (BaseException) e;
        return userError(exception);
      }
      prefix = StringUtils.isNullOrEmpty(prefix) ? "" : prefix + ":";
      ResponseMessage message = ResponseMessage.systemError(e);
      return ResponseGeneric.systemError(prefix + message.getMsg());
    } catch (Exception e2) {
      return ResponseGeneric.systemError(e2.toString());
    }
  }

  public void setSystemError(Throwable e) {
    setSystemError(e, null);
  }

  public void setSystemError(Throwable e, String prefix) {
    if (e instanceof BaseException) {
      BaseException exception = (BaseException) e;
      this.code = exception.getCode();
      this.msg = exception.getMsg();
    } else {
      prefix = StringUtils.isNullOrEmpty(prefix) ? "" : prefix + ":";
      ResponseMessage message = ResponseMessage.systemError(e);
      this.code = message.getCode();
      this.msg = message.getMsg();
    }
  }

  public static <T> ResponseGeneric<T> systemError(String msg) {
    return new ResponseGeneric<>(new ResponseMessage(BaseBusinessMessage.FAILURE_CODE, msg));
  }

  public static <T> ResponseGeneric<T> successObject() {
    return new ResponseGeneric<>();
  }

  public static <T> ResponseGeneric<T> userFailure(String msg) {
    ResponseMessage message = ResponseMessage.userFailure(msg);
    return new ResponseGeneric<>(message);
  }

  public static <T> ResponseGeneric<T> userFailure(String msg, T data) {
    ResponseMessage message = ResponseMessage.userFailure(msg);
    return new ResponseGeneric<>(message, data);
  }

  public void setMessage(ResponseMessage message) {
    this.code = message.getCode();
    this.msg = message.getMsg();
  }

  public void setUserFailure(ResponseMessage message) {
    this.code = message.getCode();
    this.msg = message.getMsg();
  }

  public static <T> ResponseGeneric<T> userSecurity(ResponseMessage message, T data) {
    return new ResponseGeneric<>(message, data);
  }
}
